package com.iflytek.application.common.springdata.jdbc.utils;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by guanxf on 2015/12/31.
 */
public class SuperBeanUtils {

    @Deprecated
    public  static void populate(Object obj,Map<String, Object> map){
        try {
            DateConverter dateConverter = new DateConverter(null);
            dateConverter.setPatterns(new String[]{"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"});
            ConvertUtils.register(dateConverter, java.sql.Date.class);
            ConvertUtils.register(dateConverter, Date.class);
            ConvertUtils.register(dateConverter,java.sql.Timestamp.class);
            BeanUtils.populate(obj, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T convertForObject(Class clazz,Map<String,Object> param ) throws IllegalAccessException, InstantiationException, NoSuchMethodException, ParseException, InvocationTargetException {
        Object value = null;
        Class[] paramTypes = new Class[1];
        Object obj = null;

            //创建实例
            obj = clazz.newInstance();
            Field[] f = clazz.getDeclaredFields();
            List<Field[]> flist = new ArrayList<Field[]>();
            flist.add(f);

            Class superClazz = clazz.getSuperclass();
            while(superClazz != null){
                f = superClazz.getFields();
                flist.add(f);
                superClazz = superClazz.getSuperclass();
            }

            for (Field[] fields : flist) {
                for (Field field : fields) {
                    String fieldName = field.getName();
                    value = param.get(fieldName);
                    if(value != null){
                        paramTypes[0] = field.getType();
                        Method method = null;
                        //调用相应对象的set方法
                        StringBuffer methodName = new StringBuffer("set");
                        methodName.append(fieldName.substring(0, 1).toUpperCase());
                        methodName.append(fieldName.substring(1, fieldName.length()));
                        method = clazz.getMethod(methodName.toString(), paramTypes);
                        method.invoke(obj, SuperBeanUtils.getValue(value.toString(), fieldName, paramTypes[0]));
                    }
                }
            }

        return (T)obj;
    }

    private static<T> T getValue(String value,String fieldName,Class<T> clazz) throws ParseException {

        if (value == null) { // 如果获取参数值为null,则返回null
            return null;
        } else if (!value.equals("")) { // 如果获取参数值不为"",则通过convertGt方法进行类型转换后返回结果
            return convertVal(value, clazz);
        } else if (clazz.getName().equals(String.class.getName())) { // 如果获取参数值为""
            return convertVal(value, clazz);
        } else {// 如果获取参数值为"",并且clazz不是是String类型,则返回null
            return null;
        }
    }

    /**
     * @param <T>
     * @param value
     * @param clazz
     * @return
     */
    private static <T> T convertVal(String value, Class<T> clazz) throws ParseException {
        if (value == null) { // 如果值为null,则返回null
            return null;
        } else if (value.equals("")
                && !clazz.getName().equals(String.class.getName())) { // 如果value值为"",而且要转为的类型不是string类型，那么就统一返回null，也就是空字符串不能转成任何其他类型的实体，只能返回null
            return null;
        } else if (Date.class.getName().equalsIgnoreCase(clazz.getName())) { // 增加对从String类型到Date
            //日期类型的转换
            Date d= null;
            try {
                SimpleDateFormat sdf_time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                d = sdf_time.parse(value);
            } catch (ParseException e) {
                SimpleDateFormat sdf_date = new SimpleDateFormat("yyyy-MM-dd");
                d = sdf_date.parse(value);
            }

            return (T) d;
        }
        return (T) ConvertUtils.convert(value, clazz);
    }






}
